package homework2;

public class AdvanceMatch extends InitMatch implements ITournament {

	ITournament feeder;
	ITournament feeder2;

	public AdvanceMatch(MatchData data, ITournament feeder, ITournament feeder2) {
		super(data);
		this.feeder = feeder;
		this.feeder2 = feeder2;
	}

	public boolean allValid() {
		return data.score.isValid() && feeder.allValid() && feeder2.allValid();
	}

	public int matchesPlayed(IBaseSport team) {
		return super.matchesPlayed(team) + feeder.matchesPlayed(team)
				+ feeder2.matchesPlayed(team);
	}

	@Override
	public boolean hasInvariant() {
		if (feeder.depth() != feeder2.depth())
			return false;

		if (isRanked()) {
			int lowestRank = lowestRank();
			
			if( lowestRank < 0 )
				throw new RuntimeException("Team has a rank less than 0!");
			
			int middleRank = (lowestRank + highestRank()) / 2;

			if (balancedRanking(middleRank) == false)
				return false;
		}

		return this.winnerAlwaysAdvanced();
	}

	@Override
	public int depth() {
		return 1 + feeder.depth() + feeder2.depth();
	}

	public boolean isRanked() {
		return this.data.team1 instanceof IRanked
				&& this.data.team2 instanceof IRanked;
	}

	public void assertRanked() {
		if (!isRanked()) {
			throw new RuntimeException("Tournament is not ranked!");
		}
	}

	public boolean balancedRanking(int middleRank) {
		return this.feeder.balancedRanking(middleRank)
				&& this.feeder2.balancedRanking(middleRank);
	}

	@Override
	public int lowestRank() {
		assertRanked();

		return Math.min(feeder.lowestRank(), feeder2.lowestRank());
	}

	@Override
	public int highestRank() {
		assertRanked();

		return Math.max(feeder.highestRank(), feeder2.highestRank());
	}

	@Override
	public boolean winnerAlwaysAdvanced() {

		IBaseSport team1 = this.feeder.winnerMovesOn();
		IBaseSport team2 = this.feeder2.winnerMovesOn();
		boolean feederAdavanced = this.feeder.winnerAlwaysAdvanced();
		boolean feeder2Adavanced = this.feeder2.winnerAlwaysAdvanced();
		boolean EqualTeam1 = this.data.team1.equals(team1) || this.data.team2.equals(team1);
		boolean EqualTeam2 = this.data.team2.equals(team2) || this.data.team1.equals(team2);

		return EqualTeam1 && EqualTeam2 && feederAdavanced && feeder2Adavanced;
	}
}
